﻿/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "allsqlconversationmodel.h"

#include <QDateTime>
#include <QDebug>
#include <QSqlError>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QCoreApplication>
#include <QDir>

static const char *conversationsTableName = "Conversations";

AllSqlConversationModel::AllSqlConversationModel(QObject *parent,SqlConversationModel *ptr) :
    QSqlTableModel(parent)
{
    m_ConversationModel = ptr;
    connect(this,SIGNAL(getNewMessage(QString)),m_ConversationModel,SLOT(getNewMessage(QString)));
    setTable(conversationsTableName);
    setSort(3, Qt::DescendingOrder);
    // Ensures that the model is sorted correctly after submitting a new row.
    setEditStrategy(QSqlTableModel::OnManualSubmit);
    select();
}

QString AllSqlConversationModel::recipient() const
{
    return m_recipient;
}

void AllSqlConversationModel::setRecipient(const QString &recipient)
{
    if (recipient == m_recipient)
        return;

    //    m_recipient = recipient;

    //    QString filterString;
    //    if(recipient == "GROUP"){
    //        filterString = QString::fromLatin1("(recipient = '%1')").arg(m_recipient);
    //    }
    //    else{
    //        filterString = QString::fromLatin1(
    //                           "(recipient = '%1' AND author = '%2') OR (recipient = '%3' AND author='%4')").arg(m_recipient).arg(m_meMail).arg(m_meMail).arg(m_recipient);
    //    }

    //    qDebug()<<filterString;
    //    setFilter(filterString);
    //    select();

    //    emit recipientChanged();
}

QVariant AllSqlConversationModel::data(const QModelIndex &index, int role) const
{
    if (role < Qt::UserRole)
        return QSqlTableModel::data(index, role);

    const QSqlRecord sqlRecord = record(index.row());
    return sqlRecord.value(role - Qt::UserRole);
}

QHash<int, QByteArray> AllSqlConversationModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names[Qt::UserRole] = "id";
    names[Qt::UserRole + 1] = "author";
    names[Qt::UserRole + 2] = "recipient";
    names[Qt::UserRole + 3] = "timestamp";
    names[Qt::UserRole + 4] = "message";
    names[Qt::UserRole + 5] = "type";
    names[Qt::UserRole + 6] = "answer";
    return names;
}

bool AllSqlConversationModel::sendMessage(const QString &recipient, const QString &message)
{
    if(message.toUtf8().toBase64().length()>4000){
        return false;
    }
    m_recipient = recipient;
    const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate);

    QSqlRecord newRecord = record();
    newRecord.setValue("author", m_ConversationModel->me());
    newRecord.setValue("recipient", recipient);
    newRecord.setValue("timestamp", timestamp);
    newRecord.setValue("message", message);
    newRecord.setValue("type", "1");
    newRecord.setValue("answer", "0");
    if (!insertRecord(rowCount(), newRecord)) {
        qWarning() << "Failed to send message:" << lastError().text();
        return false;
    }
    submitAll();
    emit getNewMessage(recipient);
    if(recipient=="GROUP")
        emit sendToServer(2001,QString::fromUtf8(recipient.toUtf8().toBase64()+"|"+m_ConversationModel->me().toUtf8().toBase64()+"|"+message.toUtf8().toBase64()));
    else
        emit sendToServer(2000,QString::fromUtf8(recipient.toUtf8().toBase64()+"|"+m_ConversationModel->me().toUtf8().toBase64()+"|"+message.toUtf8().toBase64()));
    return true;
}

QString AllSqlConversationModel::sendFile(const QString &recipient,const QStringList &filelist)
{
    QString command = QCoreApplication::applicationDirPath()+"/thirdpart/curl.exe";
    QFileInfo file(command);
    if(!file.exists()){
        return QStringLiteral("缺少curl工具,请检查安装包!");
    }

    foreach(QString var,filelist){
        file.setFile(var);
        if(file.isDir()){
            return QStringLiteral("暂不支持文件夹发送,请重新选择!");
        }
    }

    m_recipient = recipient;
    const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate);

    QJsonObject sV;
    foreach(QString var,filelist){
        file.setFile(var);
        QString size;
        if(file.size()<1024)
            size = QString("%1 B").arg(file.size());
        else if(file.size()<1024*1024)
            size = QString("%1 kB").arg(file.size()/1024.0,0,'f',2,QLatin1Char(' '));
        else if(file.size()<1024*1024*1024)
            size = QString("%1 MB").arg(QString::number(file.size()/1024.0/1024.0,'f',2));
        else
            size = QString("%1 GB").arg(QString::number(file.size()/1024.0/1024.0/1024.0,'f',2));
        QSqlRecord newRecord = record();
        newRecord.setValue("author", m_ConversationModel->me());
        newRecord.setValue("recipient", recipient);
        newRecord.setValue("timestamp", timestamp);
        newRecord.setValue("message", file.fileName()+"|"+size+"|"+var);
        newRecord.setValue("type", "2");
        newRecord.setValue("answer", "0|0%");
        if (!insertRecord(rowCount(), newRecord)) {
            qWarning() << "Failed to send message:" << lastError().text();
        }
        else{
            QSqlRecord sqlRecord = record(rowCount()-1);
            sV.insert("id",sqlRecord.value("id").toInt());
            sV.insert("currentIndex",rowCount()-1);
            sV.insert("author", m_ConversationModel->me());
            sV.insert("recipient", recipient);
            sV.insert("timestamp", timestamp);
            sV.insert("message", file.fileName()+"|"+size+"|"+var);
            sV.insert("filePath", var);
            sV.insert("cmdPath",command);
            sV.insert("type", "2");
            sV.insert("answer", "0");
            emit uploadFile(sV);
        }
    }
    submitAll();
    emit getNewMessage(recipient);
    return "";
}

void AllSqlConversationModel::uploadFileReturn(QJsonObject value)
{
    int preIndex = rowCount()-value.value("currentIndex").toInt()-1;
    if(value.value("curl").toInt()==0){
        if(value.value("statusValue").toString().contains("100")||value.value("status").toString().contains("100")){
            qDebug()<<"success";
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","0|100%");
            QString formateUrl = value.value("url").toString().replace(serPortF,serPortF+"/get");
            mrecord.setValue("message",mrecord.value("message").toString()+"|"+formateUrl);
            setRecord(preIndex, mrecord);

            if(m_recipient=="GROUP")
                emit sendToServer(2020,QString::fromUtf8(m_recipient.toUtf8().toBase64()+"|"+m_ConversationModel->me().toUtf8().toBase64()+"|"+mrecord.value("message").toString().toUtf8().toBase64()));
            else
                emit sendToServer(2010,QString::fromUtf8(m_recipient.toUtf8().toBase64()+"|"+m_ConversationModel->me().toUtf8().toBase64()+"|"+mrecord.value("message").toString().toUtf8().toBase64()));

        }
        else {
            qDebug()<<"fail:"<<value.value("status").toString();
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","1|"+value.value("status").toString());
            setRecord(preIndex, mrecord);
        }
        if(submitAll()){
            emit getNewMessage(value.value("recipient").toString());
        }
        else{
            qDebug()<<"fail:"<<lastError();
        }
    }
    else if(value.value("curl").toInt()==1){
        qDebug()<<value.value("status").toString();
    }
    else if(value.value("curl").toInt()==2){
        if(value.value("status").toString().contains("%")){
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","0|"+value.value("status").toString());
            setRecord(preIndex, mrecord);
            if(submitAll()){
                emit getNewMessage(value.value("recipient").toString());
            }
            else
                qDebug()<<"fail:"<<lastError();

        }
        else
            qDebug()<<value.value("status").toString();
    }
}

void AllSqlConversationModel::downLoadFileReturn(QJsonObject value)
{
    int preIndex = rowCount()-value.value("currentIndex").toInt()-1;
    if(value.value("curl").toInt()==0){
        qDebug()<<value;
        if(value.value("statusValue").toString().contains("100")){
            qDebug()<<"success";
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","0|100%");
            if(!value.value("Renamed").toString().isEmpty()){
                QStringList message = mrecord.value("message").toString().split("|");
                message.replace(0,value.value("Renamed").toString());
                mrecord.setValue("message",message.join("|"));
            }
            setRecord(preIndex, mrecord);
        }
        else {
            qDebug()<<"fail:"<<value.value("status").toString();
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","1|"+value.value("status").toString());
            setRecord(preIndex, mrecord);
        }
        if(submitAll()){
            if(value.value("recipient").toString()=="GROUP")
                emit getNewMessage("GROUP");
            else
                emit getNewMessage(value.value("author").toString());
        }
        else{
            qDebug()<<"fail:"<<lastError();
        }
    }
    else if(value.value("curl").toInt()==1){
        qDebug()<<value.value("status").toString();
    }
    else if(value.value("curl").toInt()==2){
        //        qDebug()<<"download status changed";
        if(value.value("status").toString().contains("%")){
            QSqlRecord mrecord = record(preIndex);
            mrecord.setValue("answer","0|"+value.value("status").toString().split("|").at(0));
            setRecord(preIndex, mrecord);
            if(submitAll()){
                if(value.value("recipient").toString()=="GROUP")
                    emit getNewMessage("GROUP");
                else
                    emit getNewMessage(value.value("author").toString());
            }
            else
                qDebug()<<"fail:"<<lastError();
        }
        else
            qDebug()<<value.value("status").toString();
    }
}

void AllSqlConversationModel::sendToSqlForFile(QJsonObject value)
{
    QJsonObject sV;
    QSqlRecord newRecord = record();
    newRecord.setValue("author", value.value("recipient").toString());
    newRecord.setValue("recipient", value.value("author").toString());
    newRecord.setValue("timestamp", value.value("timestamp").toString());
    newRecord.setValue("message", value.value("message").toString());
    newRecord.setValue("type", "2");
    newRecord.setValue("answer", "0|0%");
    if (!insertRecord(rowCount(), newRecord)) {
        qWarning() << "Failed to send message:" << lastError().text();
        return;
    }
    else{
        QStringList temp = value.value("message").toString().split("|");
        sV.insert("currentIndex",rowCount()-1);
        sV.insert("author", value.value("recipient").toString());
        sV.insert("recipient", value.value("author").toString());
        sV.insert("type", "2");
        sV.insert("answer", "0");
        sV.insert("fileName",temp.first());
        sV.insert("fileSize",temp.value(1));
        sV.insert("fileHttp",temp.last());
        emit downloadFile(sV);
    }
    if(submitAll()){
        if(value.value("author").toString()=="GROUP")
            emit getNewMessage("GROUP");
        else
            emit getNewMessage(value.value("recipient").toString());
    }
    else{
        qDebug()<<"fail:"<<lastError();
    }
}

void AllSqlConversationModel::sendToSql(QJsonObject value)
{
    QSqlRecord newRecord = record();
    newRecord.setValue("author", value["recipient"].toString());
    newRecord.setValue("recipient", value["author"].toString());
    newRecord.setValue("timestamp", value["timestamp"].toString());
    newRecord.setValue("message", value["message"].toString());
    newRecord.setValue("type", "1");
    newRecord.setValue("answer", "0");
    if (!insertRecord(rowCount(), newRecord)) {
        qWarning() << "Failed to send message:" << lastError().text();
        return;
    }
    if(submitAll()){
        if(value.value("author").toString()=="GROUP")
            emit getNewMessage("GROUP");
        else
            emit getNewMessage(value["recipient"].toString());
    }
    else
        qDebug()<<"fail:"<<lastError();
}

void AllSqlConversationModel::initCurrentUser(const QJsonObject &value)
{
    //    setMe(value["user_mail"].toString());
    //    setIsGroup(true);
    //    setRecipient("GROUP");
    m_ConversationModel->initCurrentUser(value);
}
